package ar.uade.edu.fain.ad.server.business;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ar.uade.edu.fain.ad.common.exception.PedidoCerradoException;
import ar.uade.edu.fain.ad.common.exception.PedidoFacturadoException;
import ar.uade.edu.fain.ad.common.transfer.CierreCajaVO;

public class Caja extends Area {

	private List<CierreCaja> cierres;
	private List<Factura> facturas;

	public Caja() {
		super();
		this.cierres = new ArrayList<CierreCaja>();
		this.facturas = new ArrayList<Factura>();
	}

	public List<CierreCaja> getCierres() {
		return cierres;
	}

	public void setCierres(List<CierreCaja> cierres) {
		this.cierres = cierres;
	}

	public List<Factura> getFacturas() {
		return facturas;
	}

	public void setFacturas(List<Factura> facturas) {
		this.facturas = facturas;
	}

	/**
	 * Crea una nueva factura en esta caja para los pedidos provistos.
	 * 
	 * @param pedidos
	 * @return la nueva factura
	 * @throws PedidoCerradoException
	 */
	public Factura facturar(final Set<Pedido> pedidos)
			throws PedidoFacturadoException {
		Factura factura = new Factura();
		factura.confeccionar(pedidos);
		factura.setCaja(this);
		return factura;
	}

	/**
	 * Genera las comisiones diarias en base a las facturas provistas.
	 * 
	 * @param facturas
	 * @return las comisiones generadas
	 */
	public Set<Comision> calcularComisionesSobre(final Set<Factura> facturas) {
		final HashSet<Comision> comisiones = new HashSet<Comision>();
		final HashMap<Mozo, Double> acumuladosPorMozo = new HashMap<Mozo, Double>();
		for (Factura factura : facturas) {
			final Mozo mozo = factura.getPedidos().iterator().next().getMozo();
			Double acumulado = acumuladosPorMozo.get(mozo);
			if (acumulado == null) {
				acumulado = 0D;
			}
			final Double totalFactura = factura.getTotal() == null ? 0D
					: factura.getTotal();
			final Double totalComisionFactura = totalFactura
					* mozo.getPorcentajeBase();
			acumulado += totalComisionFactura;
			for (ItemFactura itemFactura : factura.getItems()) {
				final Double porcentajeExtra = itemFactura.getPlatoFacturado()
						.getComisionExtra();
				if (porcentajeExtra != null && porcentajeExtra > 0D) {
					final Double precioPlato = itemFactura.getPlatoFacturado()
							.getPrecio();
					final Double totalItem = precioPlato
							* itemFactura.getCantidad();
					final Double totalComisionExtra = totalItem
							* porcentajeExtra;
					acumulado += totalComisionExtra;
				}
			}
			acumuladosPorMozo.put(mozo, acumulado);
		}
		final Date fecha = new Date();
		for (Mozo mozo : acumuladosPorMozo.keySet()) {
			final Comision comision = new Comision();
			comision.setFecha(fecha);
			comision.setMozo(mozo);
			comision.setTotal(acumuladosPorMozo.get(mozo));
			mozo.getComisiones().add(comision);
			comisiones.add(comision);
		}
		return comisiones;
	}

	public CierreCaja cerrar(final CierreCajaVO cierreCajaVO) {
		final CierreCaja cierreCaja = new CierreCaja();
		cierreCaja.setCaja(this);
		cierreCaja.setCantidadCupones(cierreCajaVO.getCantidadCuponesEnCaja());
		cierreCaja.setFecha(Calendar.getInstance().getTime());
		cierreCaja.setTotalCupones(cierreCajaVO.getTotalCuponesEnCaja());
		cierreCaja.setTotalEfectivo(cierreCajaVO.getTotalEfectivoEnCaja());
		getCierres().add(cierreCaja);
		return cierreCaja;
	}
}
